﻿Namespace Collections
    Public Class GenericCollection(Of T)
        Implements ICollection(Of T), IEnumerable(Of T), IList(Of T)

#Region "Fields"
        Private _list As IList(Of T)
        Protected _IsReadonly As Boolean
#End Region

#Region "Properties"
        Protected Overridable ReadOnly Property List() As List(Of T)
            Get
                Return _list
            End Get
        End Property

        Public Overridable ReadOnly Property Count() As Integer Implements System.Collections.Generic.ICollection(Of T).Count
            Get
                Return List.Count
            End Get
        End Property

        Public Overridable ReadOnly Property IsReadOnly() As Boolean Implements System.Collections.Generic.ICollection(Of T).IsReadOnly
            Get
                Return _IsReadonly
            End Get
        End Property

        Default Public Overridable Property Item(ByVal index As Integer) As T Implements System.Collections.Generic.IList(Of T).Item
            Get
                Return List.Item(index)
            End Get
            Set(ByVal value As T)
                If Not Me.IsReadOnly Then
                    List.Item(index) = value
                Else
                    Throw New ReadOnlyException
                End If
            End Set
        End Property

#End Region

#Region "Constructors"
        Public Sub New()
            Me.New(False)
        End Sub

        Public Sub New(ByVal isReadonly As Boolean)
            _list = New List(Of T)
            _IsReadonly = isReadonly
        End Sub
#End Region

#Region "Methods"
        Public Overridable Sub Add(ByVal item As T) Implements System.Collections.Generic.ICollection(Of T).Add
            If Not Me.IsReadOnly Then
                List.Add(item)
            Else
                Throw New ReadOnlyException
            End If
        End Sub

        Public Overridable Sub Clear() Implements System.Collections.Generic.ICollection(Of T).Clear
            If Not Me.IsReadOnly Then
                List.Clear()
            Else
                Throw New ReadOnlyException
            End If
        End Sub

        Public Overridable Function Contains(ByVal item As T) As Boolean Implements System.Collections.Generic.ICollection(Of T).Contains
            Return List.Contains(item)
        End Function

        Public Overridable Overloads Sub CopyTo(ByVal array() As T, ByVal arrayIndex As Integer) Implements System.Collections.Generic.ICollection(Of T).CopyTo
            List.CopyTo(array, arrayIndex)
        End Sub

        Public Overloads Sub CopyTo(ByVal collection As ICollection(Of T))
            Dim arr(Me.List.Count) As T
            List.CopyTo(arr)
            collection.Clear()
            For Each Item As T In arr
                collection.Add(Item)
            Next
        End Sub

        Public Overloads Sub CopyTo(ByVal array() As T)
            List.CopyTo(array)
        End Sub

        Public Overridable Function Remove(ByVal item As T) As Boolean Implements System.Collections.Generic.ICollection(Of T).Remove
            If Not Me.IsReadOnly Then
                Return List.Remove(item)
            Else
                Throw New ReadOnlyException
            End If
        End Function

        Public Overridable Function GetEnumerator() As System.Collections.Generic.IEnumerator(Of T) Implements System.Collections.Generic.IEnumerable(Of T).GetEnumerator
            Return List.GetEnumerator
        End Function

        Public Overridable Function IndexOf(ByVal item As T) As Integer Implements System.Collections.Generic.IList(Of T).IndexOf
            Return List.IndexOf(item)
        End Function

        Public Overridable Sub Insert(ByVal index As Integer, ByVal item As T) Implements System.Collections.Generic.IList(Of T).Insert
            If Not Me.IsReadOnly Then
                List.Insert(index, item)
            Else
                Throw New ReadOnlyException
            End If
        End Sub


        Public Overridable Sub RemoveAt(ByVal index As Integer) Implements System.Collections.Generic.IList(Of T).RemoveAt
            List.RemoveAt(index)
        End Sub

        Private Function GetEnumerator1() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
            Return List.GetEnumerator
        End Function
#End Region
    End Class
End Namespace